package com.tyj.movie.config.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import javax.sql.DataSource;

/**
 * 日期: 2021/6/5 8:41
 * 作者: 谭友杰
 * 类说明:
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)//注解表示启用全局方法权限管理功能。
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    @Autowired
    UserDetailServiceImpl userDetailsService;

    @Autowired
    DataSource dataSource; //配合记住我时需要用到

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * 定义认证规则
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //使用自定义认证
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //权限管理================================================================
        http.authorizeRequests()
                .antMatchers("/").permitAll() //放行所有
                .antMatchers("/personalOrder").authenticated() //拦截请求
                .antMatchers("/profile.html").authenticated()
                .antMatchers("/movie/order/selectionSeat").authenticated();

        //登录管理================================================================
        http.formLogin()
                .passwordParameter("password")  //对应前端数据
                .usernameParameter("username")  //对应前端数据
                .loginPage("/login.html") //指定登录页面
                .loginProcessingUrl("/movie/users/login"); //处理登录请
//                .defaultSuccessUrl("/") //登录成功默认跳转页面
//                .failureForwardUrl("/movie/users/error/loginError"); //指定登录失败跳转的地址

//      关闭跨站点请求伪造 默认是开启的
        http.csrf().disable();

        //退出管理================================================================
        http.logout().logoutUrl("/logout").     //退出请求
                logoutSuccessUrl("/login.html").    //退出返回页面
                deleteCookies("JSESSIONID");        //删除session

        //记住我功能==============================================================
        http.rememberMe()
                .tokenRepository(persistentTokenRepository())//配置remeberMe的token操作
                .tokenValiditySeconds(60 * 60 * 24 * 2)//配置token失效秒数
                .userDetailsService(userDetailsService);//配置操作数据库用户的service
    }

    //    开启记住我功能
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        //因为是Jdbc操作,所以我们需要注入数据源:org.springframework.jdbc.core.support.JdbcDaoSupport
        //tokenRepository继承org.springframework.jdbc.core.support.JdbcDaoSupport
        tokenRepository.setDataSource(dataSource);
//        System.out.println("PersistentTokenRepository--dataSource:>dataSource");
//        tokenRepository.setCreateTableOnStartup(true);//系统启动的时候创建:CREATE_TABLE_SQL表
        return tokenRepository;
    }


}
